home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Information
/
CSMP Digest
/
volume 3
/
csmp-digest-v3-054
< prev
next >
Wrap
Text File
|
1995-12-31
|
90KB
|
2,375 lines
Received-Date: Wed, 7 Sep 1994 18:19:26 +0200
From: pottier@clipper.ens.fr (Francois Pottier)
Subject: csmp-digest-v3-054
To: csmp-digest@ens.fr
Date: Wed, 7 Sep 1994 18:19:19 +0200 (MET DST)
X-Mailer: ELM [version 2.4 PL23]
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Errors-To: listman@ens.fr
Reply-To: pottier@clipper.ens.fr
X-Sequence: 59
C.S.M.P. Digest Wed, 07 Sep 94 Volume 3 : Issue 54
Today's Topics:
How to use AESuspendTheCurrentEvent?
Learning Macintosh Programming
Should function order be conserved? (CW vs. GestaltValue)
Sound Manager headaches (again)
Stopping a 'snd ' resource dead
[Q] What does "_Xxxxx ,Sys,Immed" mean?
jGNE from an INIT
The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
(pottier@clipper.ens.fr).
The digest is a collection of article threads from the internet newsgroup
comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
regularly and want an archive of the discussions. If you don't know what a
newsgroup is, you probably don't have access to it. Ask your systems
administrator(s) for details. If you don't have access to news, you may
still be able to post messages to the group by using a mail server like
anon.penet.fi (mail help@anon.penet.fi for more information).
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject. The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
nef.ens.fr). Article threads are not added to the digest until the last
article added to the thread is at least two weeks old (this is to ensure that
the thread is dead before adding it to the digest). Article threads that
consist of only one message are generally not included in the digest.
The digest is officially distributed by two means, by email and ftp.
If you want to receive the digest by mail, send email to listserv@ens.fr
with no subject and one of the following commands as body:
help Sends you a summary of commands
subscribe csmp-digest Your Name Adds you to the mailing list
signoff csmp-digest Removes you from the list
Once you have subscribed, you will automatically receive each new
issue as it is created.
The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
Questions related to the ftp site should be directed to
scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
digest are available there.
Also, the digests are available to WAIS users. To search back issues
with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
-------------------------------------------------------
>From phaedrus@chinook.halcyon.com (Mark Phaedrus)
Subject: How to use AESuspendTheCurrentEvent?
Date: 19 Aug 1994 21:44:57 GMT
Organization: NWNEXUS, Inc. - Making Internet Easy
Could someone please post some brief sample code showing the correct use
of AESuspendTheCurrentEvent and AEResumeTheCurrentEvent?
Basically, this is what I'm doing right now:
AppleEvent *pendingEvent,*pendingReply;
OSErr err;
pascal OSErr MyEventHandler(AppleEvent *messagein, AppleEvent *reply,
long refcon)
{
/* make sure we're allowed to put up a window */
if (noErr != (err = AEInteractWithUser(kMyTimeoutTicks,nil,nil)))
return err;
/* assorted code to display the window deleted */
/* keep track of these events for later */
pendingEvent = messagein;
pendingReply = reply;
/* we'll wait for the user to do something that triggers a response */
if (noErr != (err = AESuspendTheCurrentEvent(messagein)))
return err;
return noErr;
}
pascal OSErr MyEventCompletion(AppleEvent *messagein,AppleEvent *reply,
long refcon)
{
AEPutParamPtr(reply,keyAEResult,typeChar,(Ptr)myStuff,strlen(myStuff));
return noErr;
}
void CodeCalledWhenReadyToFinish(void)
{
err = AEResumeTheCurrentEvent(pendingEvent,pendingReply,MyEventCompletion,
0);
}
When the event handler is called, AESuspendTheCurrentEvent returns noErr,
and the event is apparently suspended correctly; at least, the caller never
gets a reply, even though the event handler returns. The problem is that the
event and reply records seem to be getting disposed immediately; pendingEvent
and pendingReply are pointing at garbage when CodeCalledWhenReadyToFinish is
called, and as a result AEResumeTheCurrentEvent fails miserably.
Any help you can give is gratefully appreciated...
--
\o\ If you're interested in books/stories with transformation \o\
\o\themes, or in furry/anthropomorphic art, email me, or anonymous-\o\
\o\ftp to ftp.halcyon.com and check the /local/phaedrus directory. \o\
\o\ Web users: Now try http://www.halcyon.com/phaedrus/Menu.html \o\
+++++++++++++++++++++++++++
>From hanrek@cts.com (Mark Hanrek)
Date: 22 Aug 1994 04:54:34 GMT
Organization: The Information Workshop
In article <33394p$cs5@news.halcyon.com>, phaedrus@chinook.halcyon.com
(Mark Phaedrus) wrote:
> Could someone please post some brief sample code showing the correct use
> of AESuspendTheCurrentEvent and AEResumeTheCurrentEvent?
> Basically, this is what I'm doing right now:
There is some example source code called "SuspendAppleEvent" that will
hopefully help.
You will find under "Inter-Application Communication" within the Snippets
collection. It is on the Developer CD and hopefully available at
ftp://ftp.apple.com/ as well.
Mark Hanrek
+++++++++++++++++++++++++++
>From bb@lightside.com (Bob Bradley)
Date: Sun, 21 Aug 1994 04:13:05 -0800
Organization: SS Software Inc.
I don't have a question of how to use AESuspendTheCurrentEvent but,
whether I should use it. When I receive an OpenDoc event, I put up a
dialog and the files attached to the OpenDoc event do not get processed
until the user hits ok in the dialog (or cancel which would not process
the documents at all). Should I suspend the OpenDoc event and resume when
(or if) the user chooses ok in the dialog or should I just let the
AppleEvent return and process the documents when the user wants?
IM Interapp Comm says the AppleEvent Manager expects the event to have
been processed when the handler returns which it wouldn't have been in my
case and I'm not sure if I should call AESuspendTheCurrentEvent (and
resume it later). It works fine though.
+++++++++++++++++++++++++++
>From paul@architecture.mcgill.ca (Paul Lalonde)
Date: Tue, 23 Aug 1994 02:28:45 GMT
Organization: McGill University School of Architecture
In article <33394p$cs5@news.halcyon.com>, phaedrus@chinook.halcyon.com
(Mark Phaedrus) wrote:
> Could someone please post some brief sample code showing the correct use
> of AESuspendTheCurrentEvent and AEResumeTheCurrentEvent?
> Basically, this is what I'm doing right now:
> [ stuff deleted ]
You have to save the actual event and reply records, not just pointers to
them. So a revised version of the snippet you posted would look like this:
AppleEvent pendingEvent,pendingReply;
pascal OSErr MyEventHandler(AppleEvent *messagein, AppleEvent *reply,
long refcon)
{
/* stuff deleted */
pendingEvent = *messagein;
pendingReply = *reply;
/* more stuff deleted */
return noErr;
}
void CodeCalledWhenReadyToFinish(void)
{
err = AEResumeTheCurrentEvent(&pendingEvent,&pendingReply,
MyEventCompletion,0);
}
Hope this helps,
Paul Lalonde
paul@architecture.mcgill.ca
---------------------------
>From dchakrav@netserv.unmc.edu (Dhruba Chakravarti)
Subject: Learning Macintosh Programming
Date: 19 Aug 1994 11:23:44 -0500
Organization: University of Nebraska Medical Center, Omaha, NE, USA
I do not know anything about programming, which should be obvious
from the header. I have a Macintosh computer and would like to
learn programming for Macintosh. Please advise me.
Regards,
Dhruba.
+++++++++++++++++++++++++++
>From mathews@ns9000.furman.edu (Owen Mathews)
Date: 19 Aug 1994 18:50:13 GMT
Organization: furman university computing center
Dhruba Chakravarti (dchakrav@netserv.unmc.edu) wrote:
: I do not know anything about programming, which should be obvious
: from the header. I have a Macintosh computer and would like to
: learn programming for Macintosh. Please advise me.
: Regards,
: Dhruba.
If you're programming in Pascal, pick up the
-Macintosh Pascal Programming Primer
by Dave Mark and ??? Reed (something like that)
**good introductory Mac book; teaches all about the Toolbox
and Mac programming fundamentals; comes with several well-thought-out
example programs to get you started
If you're using C, then try
-Macintosh C Programming Primer
same fellow(s?)
**I haven't see this one, but I assume it's the same idea.
If you're really ambitious, take a look at
-Learn C++ on the Macintosh
guess who? (I'm a real admirer of this guy)
**Also probably the same basic idea.
No matter which language you use, you'll eventually want to invest in
-Inside Macintosh
Apple Computer
**This set of reference books is the ultimate authority on all
aspects of Mac programming. It comes in two flavors: Old Inside Mac
(IM) and New IM (NIM). Old IM comes in 6 volumes that are organized
chronologically. This unfortunately means that certain related material
can be spread out over multiple volumes, forcing you to spend extra
time to find the right volume. NIM groups material logically by
subject. Each volume covers some clearly-defined area of the Mac API.
Of course, NIM's disadvantage is that when Apple releases new stuff,
you can't go and pick up the next chronological volume -- instead,
you'll probably have to go and buy half a dozen updates to the subject
volumes.
But I'm rambling.
Hey, don't let all that talk daunt you. With any of the first three books,
you can get started programming quickly and produce your first (albeit ultra-
simple) Mac application within an hour or two.
Hope this helps!
--
Owen Mathews mathews@furman.edu
<><><><><><><><><><><><><><><><><><><><>
Furman University, Computer Science Dept
+++++++++++++++++++++++++++
>From dchakrav@netserv.unmc.edu (Dhruba Chakravarti)
Date: 19 Aug 1994 17:17:42 -0500
Organization: University of Nebraska Medical Center, Omaha, NE, USA
Owen Mathews (mathews@ns9000.furman.edu) wrote:
: Dhruba Chakravarti (dchakrav@netserv.unmc.edu) wrote:
: : I do not know anything about programming, which should be obvious
: : from the header. I have a Macintosh computer and would like to
: : learn programming for Macintosh. Please advise me.
: : Regards,
: : Dhruba.
: If you're programming in Pascal, pick up the
: -Macintosh Pascal Programming Primer
: by Dave Mark and ??? Reed (something like that)
: **good introductory Mac book; teaches all about the Toolbox
: and Mac programming fundamentals; comes with several well-thought-out
: example programs to get you started
: If you're using C, then try
: -Macintosh C Programming Primer
: same fellow(s?)
: **I haven't see this one, but I assume it's the same idea.
: If you're really ambitious, take a look at
: -Learn C++ on the Macintosh
: guess who? (I'm a real admirer of this guy)
: **Also probably the same basic idea.
: No matter which language you use, you'll eventually want to invest in
: -Inside Macintosh
: Apple Computer
: **This set of reference books is the ultimate authority on all
: aspects of Mac programming. It comes in two flavors: Old Inside Mac
: (IM) and New IM (NIM). Old IM comes in 6 volumes that are organized
: chronologically. This unfortunately means that certain related material
: can be spread out over multiple volumes, forcing you to spend extra
: time to find the right volume. NIM groups material logically by
: subject. Each volume covers some clearly-defined area of the Mac API.
: Of course, NIM's disadvantage is that when Apple releases new stuff,
: you can't go and pick up the next chronological volume -- instead,
: you'll probably have to go and buy half a dozen updates to the subject
: volumes.
: But I'm rambling.
: Hey, don't let all that talk daunt you. With any of the first three books,
: you can get started programming quickly and produce your first (albeit ultra-
: simple) Mac application within an hour or two.
: Hope this helps!
: --
: Owen Mathews mathews@furman.edu
: <><><><><><><><><><><><><><><><><><><><>
: Furman University, Computer Science Dept
Thank you very much! I'll get these books and start reading.
Regards,
Dhruba.
+++++++++++++++++++++++++++
>From Chris Kueny <yun@fusion.ph.utexas.edu>
Date: 19 Aug 1994 23:37:21 GMT
Organization: The University of Texas at Austin, Austin, Texas
In article <332mag$2jq@netserv.unmc.edu> Dhruba Chakravarti,
dchakrav@netserv.unmc.edu writes:
>I do not know anything about programming, which should be obvious
>from the header. I have a Macintosh computer and would like to
>learn programming for Macintosh. Please advise me.
The C Programming Primer by Dave Mark assumes that you
know something about the C programming language (and I
assume that the Pascal Programming Primer assumes knowledge
of Pascal.) Another good book at this level is Dan Parks Sydow's
"Macintosh Programming Techniques".
But if you have no programming experience at all, then a good
one to start with is "Learn C on the Macintosh" by Dave Mark.
This has a stripped down version of Symantec's Think C compiler
that can be used to run the projects in the book. It will give you
an introduction to the C language, but won't tell you everything.
It has a good explanation of programming concepts for people
who have never done such things before. As mentioned above,
Dave also wrote "Learn C++ on the Macintosh".
A classic reference for the whole C language is "The C Programming
Language" by Kernighan & Ritchie.
I don't have much knowledge of Pascal. I think I heard someone
say that it is easier for a beginner to learn Pascal than to learn C.
Eventually you will have to buy a compiler. C and Pascal compilers
are available at good discounts for university and college students
and staff (maybe younger students too?) Used ones are also
sometimes advertised in this newsgroup.
+++++++++++++++++++++++++++
>From millsp@govonca.gov.on.ca (Phil Mills)
Date: Sat, 20 Aug 1994 13:05:05 GMT
Organization: Government of Ontario
In <332mag$2jq@netserv.unmc.edu> dchakrav@netserv.unmc.edu (Dhruba Chakravarti) writes:
>I do not know anything about programming, which should be obvious
>from the header. I have a Macintosh computer and would like to
>learn programming for Macintosh. Please advise me.
1) Decide why you want to program and what kind of program you would
like to create. The best choice in tools and information sources will
change depending on that decision.
(Without an answer to #1, there *is* no item #2. :-) )
+++++++++++++++++++++++++++
>From kenlong@netcom.com (Ken Long)
Date: Sat, 20 Aug 1994 16:52:14 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
Learn C on the Macintosh is NOT a good book for someone who has no
programming or Mac programming experience. It contains LITTLE about what
new Mac programmers are interested in.
Think THINK C!, by Dan Parks Sydow is THE book to start with. It teaches
new Mac programmers about aspects of Mac programming they WANT to know about.
-Ken-
+++++++++++++++++++++++++++
>From silicon@Simplex.NL (Silicon Island Software)
Date: 21 Aug 1994 08:28:13 GMT
Organization: Simplex Networking Amsterdam, The Netherlands.
Dhruba Chakravarti (dchakrav@netserv.unmc.edu) wrote:
: I do not know anything about programming, which should be obvious
: from the header. I have a Macintosh computer and would like to
: learn programming for Macintosh. Please advise me.
Why Visual EzC is good for learning Macintosh programming.
When you program in EzC, the Layouts of the applications with
their interface elements are all created graphically in a MacDraw
like Layout Editor. The process has little if anything to do with
programming.
The Menus of the application are also created in a graphic editor
by simply adding menus and menu items in a list.
The EzC program code is a C-like code, with all the basic syntax
and functionality the same as in normal C.
There is admittedly nothing new about creating layouts and
menus graphically. - The available 4GL languages all do that, each
in their own way. What is new though is, that EzC has a very
powerful and well known programming language, and the EzC
code can be pre-compiled into C, simply by selecting Precompile
from the menu. The resulting C code can then be compiled with
for instance MPW and the project can be made into a standalone
application.
Programs written in EzC are just as fast and small in size as
programs written from scratch in C or Pascal.
To give the curious an example of how a simple program looks
like in EzC we can take as an example a window with a text field
and listbox and an accept button. When the user keys in a name
in the text field and clicks the accept button the name appears in
the listbox.
Solving the problem:
1) The interface elements are drawn in the layout editor.
2) A menu for the application is created in the menu editor.
3) The code to do the processing is as follows:
inherit "Std:System:Window";
string *arr;
void _OpenView() {
arr=({});
LoadMenubar("Main");
}
void _Click(string name) {
if(name=="ok") {
arr+=({Get("field","text")});
Set("listbox","array",arr);
Set("field","text","");
}
}
The layout with the program code constitutes an object in EzC.
The explanation of the code is simple.
In the first line we inherit the standard behaviour of a window.
EzC is event driven, and opening a window generates an event.
To every EzC event corresponds a function. _OpenView() is one
such function. If defined in an object, it is invoked when the
event occurs. _Click() is another event handler function. It is
invoked on clicking the mouse.
The interface elements have names. The text field has the been
given the name 'field' and the listbox element is called 'listbox'
and the accept button's name is 'ok'.
The Set() function sets a property of an interface element with
given parameters, and the Get() function fetches the value of a
property of an interface element.
The code is only a few lines, and this is a functioning application,
and can be made standalone.
It is our opinion that EzC is a suitable language for learning
Macintosh programming. - Try for instance for comparison to
teach the beginner to create the above example application with
Think C using the TCL library.
The programmer does not need to study any textbook on
Macintosh programming to be able create simple applications
like the above application in EzC, nor does he need to have read a
word of the voluminous Inside Macintosh. He does however need
to know something about C programming in general and to
understand the events of EzC and to have at hand a reference
over the main kernel and Library functions in EzC.
As the programmer becomes more proficient Visual EzC will
grow with him, since it is so strongly related to C. The
programmer also gradually becomes interested in acquiring
knowledge of the Macintosh Toolbox as he needs to solve more
advanced problems.
The main advantage of learning Macintosh programming by
using EzC is that the beginner can actually create useful
standalone applications that he can be proud of within hours.
Another important advantage is, that the beginner will quickly
learn to appreciate Object Oriented programming as object
orientation is so closely woven into the EzC language.
A third advantage is, that the beginner will learn the basics of a
generally known and accepted language, C.
Last but not least. One should not forget that EzC also has a built
in relational database engine, so when the beginner wants to
create a database program, the tools are right there.
A demo of Visual EzC can be found on mac.archive.umich.edu in
the /mac/misc/demo/visualezc1.0b4-demo.hqx and on any of the
info-mac mirror sites.
Silicon Island Software
Email: silicon@simplex.nl
+++++++++++++++++++++++++++
>From D.Birnie@Regy.Canterbury.ac.nz (Denis A. Birnie)
Date: Mon, 22 Aug 1994 11:17:06 +1200
Organization: ISS
> I do not know anything about programming, which should be obvious
> from the header. I have a Macintosh computer and would like to
> learn programming for Macintosh. Please advise me.
>
Dhruba,
The current way to go language-wise is C (or C++).
The book which I'd recommend (and which uses C) is
Macintosh_Programming_Secrets (2nd edition) by Scott Knaster & Keith
Rollin. Shows you all sorts of interesting and neat things as well as
giving you a skeleton application to work from. A VERY good book.
I'd also suggest Think Reference if you get serious and have a screen
larger than the original 9"ers.
Denis Birnie
--
COBOhoLic!
+++++++++++++++++++++++++++
>From hanrek@cts.com (Mark Hanrek)
Date: 22 Aug 1994 05:04:10 GMT
Organization: The Information Workshop
In article <332mag$2jq@netserv.unmc.edu>, dchakrav@netserv.unmc.edu
(Dhruba Chakravarti) wrote:
> I do not know anything about programming, which should be obvious
> from the header. I have a Macintosh computer and would like to
> learn programming for Macintosh. Please advise me.
>
Dhruba,
Besides all the excellent suggestions and advice thus far, consider doing
the following...
Decide on a language, and get the compiler for it.
Then, download all the example source code you can find in that language
and compile it.
If something is too hard to get going, move on to another.
When you get something to compile successfully, and it runs, then maybe
you can think of an easy way to tweak it or make it do something
different.
- --
This method is an excellent method, because you will quickly become
familiar with your development environment, and the language, and the
Macintosh Toolbox (the three things you'll be learning at the same time).
But what is great about this approach is that you will be getting a sense
of gratification as you go along, and you will always be modifying rather
than creating -- these are two very important things in the beginning, and
two of the major reasons many people give up.
There's no need to overwhelm yourself. Always have a language reference handy.
So compile freely downloadable program right and left, have fun, make some
changes that make goofy things happen, and next thing you know, you will
have subliminally learned a ton of essential things without even noticing
it.
Good luck to you.
Mark Hanrek
The Information Workshop
+++++++++++++++++++++++++++
>From garyg@oak.circa.ufl.edu
Date: 22 Aug 1994 12:46:50 GMT
Organization: Center for Instructional and Research Computing Activities
Dhruba,
In addition to the other advice offered, I'd suggest that you also get:
Macintosh Programming Techniques: A Foundation for All Macintosh
Programmers by Dan Parks Sydow (1994; M&T Books). It includes a
diskette with interactive tutorials, sample code with small built
applications (in case you don't have a C compiler yet), and lots
of highly useful info. Another great job by DPSydow!!
hth, Gary
+++++++++++++++++++++++++++
>From dchakrav@netserv.unmc.edu (Dhruba Chakravarti)
Date: 23 Aug 1994 11:27:23 -0500
Organization: University of Nebraska Medical Center, Omaha, NE, USA
garyg@oak.circa.ufl.edu wrote:
: Dhruba,
: In addition to the other advice offered, I'd suggest that you also get:
: Macintosh Programming Techniques: A Foundation for All Macintosh
: Programmers by Dan Parks Sydow (1994; M&T Books). It includes a
: diskette with interactive tutorials, sample code with small built
: applications (in case you don't have a C compiler yet), and lots
: of highly useful info. Another great job by DPSydow!!
: hth, Gary
Thank you all very much!
Regards,
Dhruba.
---------------------------
>From will@cs.su.oz.au (William Uther)
Subject: Should function order be conserved? (CW vs. GestaltValue)
Date: 20 Aug 1994 16:19:54 +1000
Organization: Basser Dept of Computer Sciece, Uni of Sydney, Australia
Hi,
I am using CodeWarrior to write a small application. I want this application
to publish a handle. I had an earlier version that did this using the
GestaltValue library. This library does not work with CW 3.5.
I traced it, and found that the reason it didn't work was because it relied
upon the ordering of functions to find the size of a block of memory to
allocate. (it subtracted the address of the start of one function from the
address of the start of another function to get the size of the first function
and hence the amount of memory it had to allocate to copy it to the system heap)
CW 3.5 does not respect this ordering when it converts Apple's '.o' file into
a library.
Is this a problem for MetroWerks (CW SHOULD respect the function ordering),
or is this a problem for Apple (DTS shouldn't write libraries that rely on
function ordering)?? At the moment it just seems to be a problem for me....
Metrowerks tech support were very good at verifying the problem,
unfortunately, since they shifted the blame to Apple they haven't done much.
(BTW the library works in THINK C 5.0, 6.0 and 7.0 - I assume it works in MPW
as it's an MPW object file)
Should I be talking to Apple DTS or Metrowerks tech support?
\x/ill :-}
will@cs.su.oz.au
+++++++++++++++++++++++++++
>From cokenias@netcom.com (Damon Cokenias)
Date: Sun, 21 Aug 1994 21:16:36 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
- ---
I traced it, and found that the reason it didn't work was because it relied
upon the ordering of functions to find the size of a block of memory to
allocate. (it subtracted the address of the start of one function from the
address of the start of another function to get the size of the first function
and hence the amount of memory it had to allocate to copy it to the system heap)
CW 3.5 does not respect this ordering when it converts Apple's '.o' file into
a library.
- ---
Every time I'm stepping through somebody's INIT trying to find out if it is
responsible for crashing my machine, I invariably find this sort of programming.
It is sick and immoral. It is absolutely none of the programmer's business
where or how their code gets compiled.
There are two solutions to the Patch/Gestalt Selector/Shutdown Handler install
problem. (Actually, there are more than two, but these are my favorites).
** A **
1) Call Get1IndResource (INIT, 1) to find yourself (or other appropriate
GetResource call)
2) Detach yourself, install all patches, etc.
** B **
1) Load a code resource containing your patch routines, detach and lock
2) Install patches.
I typically use A for quickie jobs that I just want to crank out in a moment
or two. It has the disadvantage of leaving the loader code behind. Some of
the advantages are: Only one binary to build (nice for THINK and CW users),
the patches have access to the same A4 globals the loader code did. This
can be usefull.
I choose B for lean and mean INITs that I release to the public. In order to
initialize the globals for the code resource with values from the loader, I
sometimes do the following:
1) Inside the code resource I have an A4 global called 'intialized'. It's
initial value is zero.
2) BEFORE installing the patches, I call my code resource, passing a pointer
to a structure containing initial values. This can only be done for patches
that accept parameters, obviously.
3) If 'initialized' is still false, the code resource knows the passed parameter
contains special data and uses that data. 'initialized' is then set to true.
4) From this point on, all calls to the code resource are treated as one would
expect them to.
Often, this is the most convenient way to tell a patch where to jump to after
completion. It is 100% portable on all platforms that allow a standalone
code resource to have globals.
DO NOT:
* assume code gets put anywhere. If you use Codewarrior, the frequent
updates and changes should cure you of that fast enough.
(What if CW noticed that a particular routine could be called with a short
branch instead of a long one? It might re-arrange certain funtions to make
them closer to their callers.)
-Damon Cokenias
.
--
Damon Cokenias
cokenias@netcom.COM
+++++++++++++++++++++++++++
>From h+@nada.kth.se (Jon W{tte)
Date: Mon, 22 Aug 1994 14:54:28 +0200
Organization: Royal Institute of Something or other
In article <cokeniasCuwLro.J8@netcom.com>,
cokenias@netcom.com (Damon Cokenias) wrote:
>It is sick and immoral. It is absolutely none of the programmer's business
>where or how their code gets compiled.
Yes; it definately is. For a well-defined runtime architecture,
like the Mac 68k one, you're allowed and sometimes forced to do
this.
>There are two solutions to the Patch/Gestalt Selector/Shutdown Handler install
>problem. (Actually, there are more than two, but these are my favorites).
>1) Call Get1IndResource (INIT, 1) to find yourself (or other appropriate
> GetResource call)
>2) Detach yourself, install all patches, etc.
>1) Load a code resource containing your patch routines, detach and lock
>2) Install patches.
Strangely enough, I use none of these. Instead, I get the
address of the first instruction (you can use A0 as well, but
it's slightly less safe - someone COULD have jumped to you
through another register) Then I call RecoverHandle and
DetachResource, and use PC-relative addressing to install my
patches (and store data) This requires your INIT to be marked
pre-loaded, system heap and locked.
>1) Inside the code resource I have an A4 global called 'intialized'. It's
A4 globals are much more horrible than comparing addresses of
functions. A4 globals require you to always enter through
main(), unless you do extra inline assembly, which kind of
rules out the case where the loader and the patch are in the
same code resource.
PS: you can get by the loader-left problem by putting the
loader code last, branch to it from the top and then call
SetHandleSize.
--
Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
"Don't Deal with a Dragon."
+++++++++++++++++++++++++++
>From Jaeger@fquest.com (Brian Stern)
Date: 22 Aug 1994 17:00:11 GMT
Organization: The University of Texas at Austin, Austin, Texas
In article <9668AA7E6CA4.FDF19@klkmac008.nada.kth.se>, h+@nada.kth.se (Jon
W{tte) wrote:
> A4 globals are much more horrible than comparing addresses of
> functions. A4 globals require you to always enter through
> main(), unless you do extra inline assembly, which kind of
> rules out the case where the loader and the patch are in the
> same code resource.
>
This isn't true. With A4 globals you must enter through main *once*. You
save the address of A4 in main. After that you can enter through any
entry point you like. Each additional entry point first retrieves A4 and
can then access its globals. It restores A4 before exiting. There is no
reason you can't have the loader and the patch in the same code resource.
> PS: you can get by the loader-left problem by putting the
> loader code last, branch to it from the top and then call
> SetHandleSize.
I agree that this is a neat trick. Unfortunately you can't use it when
using A4 global addressing. The globals end up at the end of the code
resource. Oh well.
> --
> Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
> "Don't Deal with a Dragon."
--
Brian Stern :-{)}
Jaeger@fquest.com
+++++++++++++++++++++++++++
>From h+@nada.kth.se (Jon W{tte)
Date: Tue, 23 Aug 1994 08:54:14 +0200
Organization: Royal Institute of Something or other
In article <Jaeger-2208941202170001@slip-2-18.ots.utexas.edu>,
Jaeger@fquest.com (Brian Stern) wrote:
>This isn't true. With A4 globals you must enter through main *once*. You
>save the address of A4 in main. After that you can enter through any
>entry point you like. Each additional entry point first retrieves A4 and
>can then access its globals. It restores A4 before exiting. There is no
>reason you can't have the loader and the patch in the same code resource.
How do you retrieve the stored value of A4 without extra inline
assembly? Or does Symantec provide the extra assembler to do it
for you from anywhere now ?(it was a long time since I last used
it...)
Cheers,
/ h+
--
Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
"Psychotherapist" - "Phycho-The-Rapist"
Pure coincidence? You decide!
+++++++++++++++++++++++++++
>From Jaeger@fquest.com (Brian Stern)
Date: 23 Aug 1994 16:19:46 GMT
Organization: The University of Texas at Austin, Austin, Texas
In article <9668AA7F69B6.206994@klkmac012.nada.kth.se>, h+@nada.kth.se
(Jon W{tte) wrote:
> How do you retrieve the stored value of A4 without extra inline
> assembly? Or does Symantec provide the extra assembler to do it
> for you from anywhere now ?(it was a long time since I last used
> it...)
>
> Cheers,
> / h+
> --
> Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
> "Psychotherapist" - "Phycho-The-Rapist"
> Pure coincidence? You decide!
Yes, the inline code is provided in a header file that must be included in
each source file that needs to do A4 addressing. The header contains
several inline assembler functions for saving and restoring A4. From the
standpoint of the programmer there is no assembly required.
--
Brian Stern :-{)}
Jaeger@fquest.com
+++++++++++++++++++++++++++
>From phils@bedford.symantec.com (Phil Shapiro)
Date: Tue, 23 Aug 1994 19:31:26 -0400
Organization: Symantec Corp.
In article <9668AA7F69B6.206994@klkmac012.nada.kth.se>, h+@nada.kth.se
(Jon W{tte) wrote:
| In article <Jaeger-2208941202170001@slip-2-18.ots.utexas.edu>,
| Jaeger@fquest.com (Brian Stern) wrote:
|
| >This isn't true. With A4 globals you must enter through main *once*. You
| >save the address of A4 in main. After that you can enter through any
| >entry point you like. Each additional entry point first retrieves A4 and
| >can then access its globals. It restores A4 before exiting. There is no
| >reason you can't have the loader and the patch in the same code resource.
|
| How do you retrieve the stored value of A4 without extra inline
| assembly? Or does Symantec provide the extra assembler to do it
| for you from anywhere now ?(it was a long time since I last used
| it...)
Each source file gets its own copy of A4. As long as you're in the same
source file that you called RememberA0() in (or RememberA4(), if A4 was
valid already), you can call SetUpA4() at any entry point. This is because
A4 is stored inside code in a static function; each file that uses the
function gets a different copy. This has been true for quite awhile, I'm
pretty sure that LSC 4.0 worked this way.
If you build with a custom header, you don't even need to enter main() at
all. But you better set up A4 before you access any globals or
cross-segment routines.
-phil
---------------------------
>From "Andrew C. Plotkin" <ap1i+@andrew.cmu.edu>
Subject: Sound Manager headaches (again)
Date: Sun, 21 Aug 1994 14:42:43 -0400
Organization: Information Technology Center, Carnegie Mellon, Pittsburgh, PA
When we last left our hero, he had just figured out how to play a sound
at a given frequency (by sending soundCmd and freqDurationCmd to a
sampledSynth channel.) (I sent a code snippet of doing this to
alt.sources.mac, if you care. ./vol-08/sampledsnd.cpt.hqx)
Well, there was a reason I wanted to do that. See, I want to get music
out, and I thought that the way to do that was record snd resources of
each instrument, and then use that technique to play notes. Allocate
several channels, you can get multiple notes at once.
...Riiiiight.
First problem: they don't start off in synch. I use the algorithm given
in the PlayTwoSoundsSynched in the SM3.0 tech note: (warning:
pseudocode, not real code, ahead)
SndDoImmediate(chan1, syncCmd{3, kID})
SndDoCommand(chan1, restCmd{500});
SndDoCommand(chan1, freqDurationCmd{500, MIDDLE_C});
SndDoImmediate(chan2, syncCmd{3, kID})
SndDoCommand(chan2, restCmd{500});
SndDoCommand(chan2, freqDurationCmd{500, MIDDLE_G});
SndDoImmediate(chan1, syncCmd{1, kID})
I expect this to pause a quarter-second, then play a nice chord. Nope.
One channel (the first one, I believe) starts slightly -- but audibly --
first. (They do finish together, though.) This occurs both with and
without SM3.0.
(My guess: the SM has to resample one or both sounds to a different
frequency, and this takes some time. Sigh.)
Oh, yeah -- syncCmd behaves with extreme magic. I still don't know
exactly what it does. For example, if I change the last line in the
algorithm above from chan1 to chan2, only one note plays instead of
both. Huh?
Second problem: Under SM3.0, if I play a sequence of notes of the same
duration, they don't come out with the same duration. Again, the
difference is pretty audible -- as much as a 50% error in short notes.
Unless I can do something about this, my entire plan is screwed. (Kinda
cool, huh? The nifty new SM *doesn't support freqDurationCmd* in a
usable form. I was pleased.) I recall someone else posted about this a
few weeks ago, and he couldn't get it to work either.
(My guess: same reason as before. The SM *does* keep the same
(distorted) time between channels; if I start two parallel synched
sequences, they stay synched. I guess that's something. It still ruins
the music, though.)
My question, pretty much, is "Have I missed anything?" I don't think I
have. I think I'm going to have to ditch the whole idea of
freqDurationCmd, and write my *own* sound-resampling-and-playing module
a la SoundTracker. (Or just use SoundTracker or some other MOD player.
This is tempting, but I haven't seen a freeware MOD player which
includes source code, except for an icky-looking one ported straight
from Unix, with malloc() everywhere. Anyone? Anyone?)
ObBribery: if you give me a magic answer that fixes my music-playing
code, I'll release the code as freeware. And I'll throw in the
simple-but-oh-so-elegant music editor I've spent the past month on.
(OTOH, if I wind up writing a MOD-style thing, I'll do the same thing.
Nevertheless.)
--Z
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
+++++++++++++++++++++++++++
>From Rick_Holzgrafe@taligent.com (Rick Holzgrafe)
Date: Mon, 22 Aug 1994 18:22:58 GMT
Organization: Semicolon Software
In article <siJu0X_00gpI9iY0YJ@andrew.cmu.edu>, "Andrew C. Plotkin"
<ap1i+@andrew.cmu.edu> wrote:
> Second problem: Under SM3.0, if I play a sequence of notes of the same
> duration, they don't come out with the same duration. Again, the
> difference is pretty audible -- as much as a 50% error in short notes.
> Unless I can do something about this, my entire plan is screwed. (Kinda
> cool, huh? The nifty new SM *doesn't support freqDurationCmd* in a
> usable form. I was pleased.) I recall someone else posted about this a
> few weeks ago, and he couldn't get it to work either.
That was me, I think. I've heard The Word from The Source: a key
programmer at Apple tells me that SM 3.0 has been optimized for playing
sampled sounds. The optimizations DE-optimized for playing melodies via
freqDurationCmd; something about internal buffers having a size that
causes perceptible delays when they need to be refilled. There is no
workaround. For my app, I had to give up on freqDurationCmds (under SM
3.0) and convert my tunes to single sampled sound resources, which
increased their size by two orders of magnitude and (to keep them from
getting even larger) decreased their sound quality. My app now tests the
version of the Sound Manager; if it is 3.0, you get one and only one
melody; if less than 3.0, you get a rotating selection out of a list of
seven melodies. The seven melodies take up about 20K of disk space; the
one sampled-sound melody takes several times that. Feh.
FWIW, I can show you code that should solve your synchronization problem.
Your various melodic parts will start together correctly, and they will
stay synched. Doesn't help the uneven tempo, though.
-- Rick Holzgrafe
Semicolon Software
rmh@taligent.com
+++++++++++++++++++++++++++
>From h+@nada.kth.se (Jon W{tte)
Date: Tue, 23 Aug 1994 09:49:07 +0200
Organization: Royal Institute of Something or other
In article <Rick_Holzgrafe-2208941123020001@ricks-cafe.taligent.com>,
Rick_Holzgrafe@taligent.com (Rick Holzgrafe) wrote:
>version of the Sound Manager; if it is 3.0, you get one and only one
>melody; if less than 3.0, you get a rotating selection out of a list of
>seven melodies. The seven melodies take up about 20K of disk space; the
>one sampled-sound melody takes several times that. Feh.
With QuickTime 2.0, however, all you do is store a General MIDI
file in your resource fork (3-10k) and there's your melody.
Luckily, this isn't rec.music.makers.synth, where "General
MIDI" is a cuss word.
Cheers,
/ h+
--
Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
"Psychotherapist" - "Phycho-The-Rapist"
Pure coincidence? You decide!
+++++++++++++++++++++++++++
>From Rick_Holzgrafe@taligent.com (Rick Holzgrafe)
Date: Tue, 23 Aug 1994 18:24:34 GMT
Organization: Semicolon Software
In article <Rick_Holzgrafe-2208941123020001@ricks-cafe.taligent.com>,
Rick_Holzgrafe@taligent.com (Rick Holzgrafe) wrote:
>version of the Sound Manager; if it is 3.0, you get one and only one
>melody; if less than 3.0, you get a rotating selection out of a list of
>seven melodies. The seven melodies take up about 20K of disk space; the
>one sampled-sound melody takes several times that. Feh.
In article <9668AA7F7693.236F39@klkmac012.nada.kth.se>, h+@nada.kth.se
(Jon W{tte) wrote:
> With QuickTime 2.0, however, all you do is store a General MIDI
> file in your resource fork (3-10k) and there's your melody.
Great. So now instead of checking for the version of the Sound Manager and
having two methods of playing music, I must also check for the presence
and version of QuickTime, and have THREE methods. Ain't progress
wonderful?
Your pardon, please, for my surliness. I'm just tired of carefully coding
to Apple's published interfaces, and having my sound code break anyway
every couple of years.
-- Rick Holzgrafe
Semicolon Software
rmh@taligent.com
---------------------------
>From mdc14@ciao.cc.columbia.edu (Michael D Coble)
Subject: Stopping a 'snd ' resource dead
Date: 23 Aug 1994 03:53:01 GMT
Organization: Columbia University
I am a programming student trying to write a couple of macintosh
applications. I recorded some music into a 'snd ' resource and want to
invoke the music when a user chooses the about this application from the
apple menu accompanied by a little animation. The 'snd ' resource is a
couple of minutes long, so I'd like to be able to allow a user to click
the close box and stop it in its tracks. I wonder if one of you
experienced programmers out there might point me in the direction to
reach this goal.
Thanks, Michael Coble, mdc14@columbia.edu
+++++++++++++++++++++++++++
>From bb@lightside.com (Bob Bradley)
Date: Sun, 21 Aug 1994 15:12:37 -0800
Organization: SS Software Inc.
In article <33brqt$mi8@apakabar.cc.columbia.edu>,
mdc14@ciao.cc.columbia.edu (Michael D Coble) wrote:
> I am a programming student trying to write a couple of macintosh
> applications. I recorded some music into a 'snd ' resource and want to
> invoke the music when a user chooses the about this application from the
> apple menu accompanied by a little animation. The 'snd ' resource is a
> couple of minutes long, so I'd like to be able to allow a user to click
> the close box and stop it in its tracks. I wonder if one of you
> experienced programmers out there might point me in the direction to
> reach this goal.
You can do this by playing the sound async. Something like this:
SndNewChannel(...) // Create a new sound channel
soundHandle = GetResource(...) // Get the snd resource
SndPlay(...) // Play the sound setting async to true
SndDisposeChanne(...) // Dispose of the sound channel and setting
// quietNow to true so it stops any sound
// that is currently playing.
Hope that helps and doesn't contain too many errors :)
+++++++++++++++++++++++++++
>From reed@medicine.wustl.edu (Thomas Reed)
Date: Tue, 23 Aug 1994 11:08:58 -0500
Organization: Washington University
If you ftp to thomas_mac.wustl.edu, you'll find the source code for a
solitaire game I wrote a while back. It contains some very useful
libraries I've written -- one of which is a sound library. Not only will
it let you do what you want to do, but it'll also let you play the sound
from disk to reduce the memory requirements.
Hope you like it!
Oh, for those of you with NewsWatcher, here's the URL:
ftp://thomas_mac.wustl.edu/Public/for_ftp/Solitaire_code.sit
-Thomas
=====================================================
Thomas Reed Washington University
reed@telesphere.wustl.edu Medical School
reed@medicine.wustl.edu Saint Louis, MO
- ---------------------------------------------------
Clothes make the man. Naked people have little or no
influence on society. -- Mark Twain
=====================================================
Opinions posted are not the opinions of Wash. U.
---------------------------
>From chris-b@cs.auckland.ac.nz (Chris Burns)
Subject: [Q] What does "_Xxxxx ,Sys,Immed" mean?
Date: Wed, 24 Aug 1994 11:36:07 +1200
Organization: AucklandUniversity:ComputerScience:HMU
Hi all,
What do the ",Sys,Immed" qualifiers mean?
I know they specify certain bits in the trap word, but what do the
different combinations mean?
What I want is a table:
Sys Immed Meaning
x x ?
x ?
x ?
?
Thanks Heaps In Advance,
Chris B
- ---------------------------------------------------------------------
NewZealand:AucklandUniversity:ComputerScience:HyperMediaUnit:ChrisBurns
Internet: chris-b@cs.auckland.ac.nz
Phone: +64 9 373-7599 x6194
Fax: +64 9 373-7453 Async, therefore I am.
- ---------------------------------------------------------------------
+++++++++++++++++++++++++++
>From wysocki@netcom.com (Chris Wysocki)
Date: Wed, 24 Aug 1994 15:27:25 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
In article <chris-b-2408941136070001@hmu7.cs.aukuni.ac.nz>,
Chris Burns <chris-b@cs.auckland.ac.nz> wrote:
>What do the ",Sys,Immed" qualifiers mean?
>I know they specify certain bits in the trap word, but what do the
>different combinations mean?
The ",Sys" and ",Immed" qualifiers displayed by MacsBug can be
misnomers, since these are only two of the possible meaning of bits 9
and 10 of a trap word. All the possible meaning for these bits can be
found in Traps.a:
; Equates for setting trap option bits
; for Device and File Manager routines
immed EQU $200 ; execute immediately, bypass I/O queue
async EQU $400 ; asynchronous, don't wait for completion
; for Memory Manager routines
clear EQU $200
sys EQU $400
; for string routines
marks EQU $200 ; set to ignore/strip diacriticals
case EQU $400 ; set for case sensitivity
; for all Toolbox routines
autoPop EQU $400 ; set to pop an extra return address
; for Get/Set & NGet/NSet TrapAddress
newTool EQU $600 ; Toolbox trap, under new ordering
newOS EQU $200 ; OS trap, under new ordering
; for HFS routines
newHFS EQU $200
Chris.
---------------------------
>From chrism@col.hp.com (Chris Magnuson)
Subject: jGNE from an INIT
Date: 17 Aug 1994 05:50:18 GMT
Organization: HP Colorado Springs Division
I am writing a jGNE event filter in MPW that needs to be part of an INIT that
does alot of other things ( i.e. the jGNE function is one part of the
INIT code resource). I've gotten alot done, but run into problems when
events actually call my jGNE routine to do the event "interception/
redirection."
short JGNEFilterFunc(short hasEvent, const EventRecord *theEvent)
My question is this: when the JGNEFilterFunc routine is called with an
EventRecord, etc. am I supposed to be doing some A5 world swapping to
get things to be handled properly in the jGNE routine? Without posting
alot of code here is basically what the INIT initialization does. Hints
are greatly appreciated!
main() {
oldZone = GetZone();
SetZone(SystemZone());
MakeA5World(&A5Ref);
if (A5Ref == nil) {
SetZone(oldZone);
return(memFullErr);
}
a_SetA5Ref(A5Ref);
oldA5 = SetA5World(A5Ref);
(void) ReadPrefs();
jGNEInit(); /* point to assembly glue routine that eventually calls
* JGNEFilterFunc() when events go through jGNE 0x29A
*/
(void) SetA5(oldA5);
SetZone(oldZone);
}
Chris Magnuson
chrism@col.hp.com
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Tue, 16 Aug 1994 23:10:27 -0800
Organization: Integer Poet Software
In article <32s8eq$kdr@hp-col.col.hp.com>,
chrism@col.hp.com (Chris Magnuson) wrote:
> I am writing a jGNE event filter in MPW that needs to be part of an INIT...
> am I supposed to be doing some A5 world swapping... ?
You will want to read the DSC Technical Note "Stand-alone Code Resources
Ad Nauseum" if you have not already. The short answer is yes, you do need
to do some twiddling to get access to global variables.
Frankly, though, I would recommend doing this project in THINK C, because
(a) assembly code is easier to integrate, (b) global variables are easier
to access, and (c) my sample jGNE INIT, "jGNE Helper", is posted monthly
to 'alt.sources.mac' with a THINK C project and will make all of these
problems go away for you.
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"I am Homer of Borg! Prepare to be... Ooooooo! Donuts!"
+++++++++++++++++++++++++++
>From neil_ticktin@xplain.com (Neil Ticktin)
Date: Wed, 17 Aug 1994 16:26:42 GMT
Organization: MacTech Magazine/Xplain Corporation
In article <32s8eq$kdr@hp-col.col.hp.com>, chrism@col.hp.com (Chris
Magnuson) wrote:
>> I am writing a jGNE event filter in MPW that needs to be part of an
INIT that
>> does alot of other things ( i.e. the jGNE function is one part of the
>> INIT code resource). I've gotten alot done, but run into problems when
>> events actually call my jGNE routine to do the event "interception/
>> redirection."
>>
Chris,
Late last year, there was a great article by Symantec Tech Support in
about writing a jGNEFilter. It was one of the THINK Top 10 columns. It
contained the template code and an example of how to do it. I'm on the
road and don't have the issue handy, but you should check it out.
Hope it helps,
Neil
- ---------------------------------------------------------------------
Neil Ticktin, MacTech Magazine (formerly MacTutor)
PO Box 250055, Los Angeles, CA 90025 * 310-575-4343 * Fax: 310-575-0925
For more info, anonymous ftp to ftp.netcom.com and cd to /pub/xplain
custservice@xplain.com * editorial@xplain.com * adsales@xplain.com
marketing@xplain.com * accounting@xplain.com * pressreleases@xplain.com
progchallenge@xplain.com * publisher@xplain.com * info@xplain.com
+++++++++++++++++++++++++++
>From chrism@col.hp.com (Chris Magnuson)
Date: 17 Aug 1994 20:14:57 GMT
Organization: HP Colorado Springs Division
Pete Gontier (gurgle@dnai.com) wrote:
: In article <32s8eq$kdr@hp-col.col.hp.com>,
: chrism@col.hp.com (Chris Magnuson) wrote:
: > I am writing a jGNE event filter in MPW that needs to be part of an INIT...
: > am I supposed to be doing some A5 world swapping... ?
: You will want to read the DSC Technical Note "Stand-alone Code Resources
: Ad Nauseum" if you have not already. The short answer is yes, you do need
: to do some twiddling to get access to global variables.
: Frankly, though, I would recommend doing this project in THINK C, because
: (a) assembly code is easier to integrate, (b) global variables are easier
: to access, and (c) my sample jGNE INIT, "jGNE Helper", is posted monthly
: to 'alt.sources.mac' with a THINK C project and will make all of these
: problems go away for you.
No it won't :) I must not be communicating what has to happen here. main()
is no longer the entry point for a jGNE filter only. main() is the entry
point for an entire INIT, one component of which is a jGNE event processor.
So the code resource in question here is an entire INIT, not just a jGNE
filter.
In other words, the jGNE portion of the code is one routine within the INIT
code resource, and I have glue that dispatches to that routine, but it
does not behave properly.
So maybe the question is, when the jGNE event is dispatched to the code
within my INIT, must I set A5 for some reason? Even though I am not
interested in globals (just the parameters on the stack)?
Chris Magnuson
chrism@col.hp.com
+++++++++++++++++++++++++++
>From chrism@col.hp.com (Chris Magnuson)
Date: 17 Aug 1994 20:16:09 GMT
Organization: HP Colorado Springs Division
Thanks. Yes, I did check that out. It doesnt answer my question since it
is a standalone jGNE (in other words the jGNE event processor is not part
of a larger code resource with other things going on).
Chris Magnuson
chrism@col.hp.com
Neil Ticktin (neil_ticktin@xplain.com) wrote:
: In article <32s8eq$kdr@hp-col.col.hp.com>, chrism@col.hp.com (Chris
: Magnuson) wrote:
: >> I am writing a jGNE event filter in MPW that needs to be part of an
: INIT that
: >> does alot of other things ( i.e. the jGNE function is one part of the
: >> INIT code resource). I've gotten alot done, but run into problems when
: >> events actually call my jGNE routine to do the event "interception/
: >> redirection."
: >>
: Chris,
: Late last year, there was a great article by Symantec Tech Support in
: about writing a jGNEFilter. It was one of the THINK Top 10 columns. It
: contained the template code and an example of how to do it. I'm on the
: road and don't have the issue handy, but you should check it out.
: Hope it helps,
: Neil
: -----------------------------------------------------------------------
: Neil Ticktin, MacTech Magazine (formerly MacTutor)
: PO Box 250055, Los Angeles, CA 90025 * 310-575-4343 * Fax: 310-575-0925
: For more info, anonymous ftp to ftp.netcom.com and cd to /pub/xplain
: custservice@xplain.com * editorial@xplain.com * adsales@xplain.com
: marketing@xplain.com * accounting@xplain.com * pressreleases@xplain.com
: progchallenge@xplain.com * publisher@xplain.com * info@xplain.com
+++++++++++++++++++++++++++
>From larson@oahu.cs.ucla.edu (Christopher Larson)
Date: Wed, 17 Aug 94 21:28:50 GMT
Organization: UCLA, Computer Science Department
In article <32tr42$pfg@hp-col.col.hp.com> chrism@col.hp.com (Chris Magnuson) writes:
>: In article <32s8eq$kdr@hp-col.col.hp.com>,
>: chrism@col.hp.com (Chris Magnuson) wrote:
>
>: > I am writing a jGNE event filter in MPW that needs to be part of an INIT...
>: > am I supposed to be doing some A5 world swapping... ?
[...]
> So maybe the question is, when the jGNE event is dispatched to the code
> within my INIT, must I set A5 for some reason? Even though I am not
> interested in globals (just the parameters on the stack)?
If you don't use (or cause to be used) any globals, you don't need an A5
world, and, therefore, you don't need to set A5.
If the jGNE filter doesn't need access to any globals, why is it part of
the INIT (I read the above to mean the jGNE code is within the INIT resource,
if not, ignore this)? Wouldn't it be easier to compile the jGNE portion as
a seperate resource, and just load, detatch, and install from the INIT
resource?
--Chris <Wondering if he's missing something obvious> Larson
_______________________________________________________________________________
Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant
L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious
Death to the Trojans! Go Bruins!
(Insert disclaimer here)
Internet: larson@kingston.cs.ucla.edu
+++++++++++++++++++++++++++
>From Jaeger@fquest.com (Brian Stern)
Date: 18 Aug 1994 00:53:36 GMT
Organization: The University of Texas at Austin, Austin, Texas
In article <32tr42$pfg@hp-col.col.hp.com>, chrism@col.hp.com (Chris
Magnuson) wrote:
> Pete Gontier (gurgle@dnai.com) wrote:
> : In article <32s8eq$kdr@hp-col.col.hp.com>,
> : chrism@col.hp.com (Chris Magnuson) wrote:
>
> : > I am writing a jGNE event filter in MPW that needs to be part of an
INIT...
> : > am I supposed to be doing some A5 world swapping... ?
>
> No it won't :) I must not be communicating what has to happen here. main()
> is no longer the entry point for a jGNE filter only. main() is the entry
> point for an entire INIT, one component of which is a jGNE event processor.
> So the code resource in question here is an entire INIT, not just a jGNE
> filter.
>
> In other words, the jGNE portion of the code is one routine within the INIT
> code resource, and I have glue that dispatches to that routine, but it
> does not behave properly.
>
> So maybe the question is, when the jGNE event is dispatched to the code
> within my INIT, must I set A5 for some reason? Even though I am not
> interested in globals (just the parameters on the stack)?
>
> Chris Magnuson
> chrism@col.hp.com
In order to function properly any jGNEFilter has to insert itself into the
chain of all jGNEFilters. When your filter exits it needs to jump to the
previous filter. The address of the previous filter must be saved at the
time that you install your filter. This saved address must be a global.
Therefore your jGNEFilter, and all jGNEFilters for all time, must have
access to global variables. There are several mechanisms for accessing
global variables in stand alone code resources like your jGNEFilter. As I
understand it MPW uses an A5-based mechanism that is described in the tech
note. Use that mechanism if you like. Think, and I believe CW, use an
A4-based mechanism, which is straightforward to use. Aside from access to
the previous filter's address or to other global variables there is no
requirement for an A5 world to be set up.
There is a sample jGNEFilter written by Dave Falkenberg that can be found
at ftp.apple.com. This sample is all in MPW assembler. It does not use
the A5 mechanism for storing the address of the previous filter. It
simply stores the address within itself.
--
Brian Stern :-{)}
Jaeger@fquest.com
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Wed, 17 Aug 1994 21:17:15 -0800
Organization: Integer Poet Software
In article <1994Aug17.212850.10867@cs.ucla.edu>, larson@oahu.cs.ucla.edu
(Christopher Larson) wrote:
> If the jGNE filter doesn't need access to any globals, why is it part of
> the INIT ... ? Wouldn't it be easier to compile the jGNE portion as
> a seperate resource, and just load, detatch, and install from the INIT
> resource?
His filter might want to call other functions in the INIT without
duplicating them in the jGNE resource. I don't know enough about
MPW-generated code resources to be able to say whether it needs A5 to call
functions. Probably it uses PC-relative calls, but it's something you
would want to look up.
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"Even during a particularly harsh (Colorado) winter... many of the
300 families in the VCTV (movies-on-demand) trial continued to go
to video stores." -- eis@murrow.tufts.edu, in Wired 2.09 p62
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Wed, 17 Aug 1994 21:25:33 -0800
Organization: Integer Poet Software
In article <32tr42$pfg@hp-col.col.hp.com>, chrism@col.hp.com (Chris
Magnuson) wrote:
> I must not be communicating what has to happen here. main()
> is no longer the entry point for a jGNE filter only. main() is the entry
> point for an entire INIT, one component of which is a jGNE event processor.
> So the code resource in question here is an entire INIT, not just a jGNE
> filter. In other words, the jGNE portion of the code is one routine within
> the INIT code resource, and I have glue that dispatches to that routine,
> but it does not behave properly.
As I said in email, I know. :-) Probably I am the one who did insufficient
communicating. With a THINK (or CodeWarrior) compiler, what you're asking
about is trivial, because the compiler actually knows that it's compiling
something other than an application, unlike MPW. MPW only knows at link
time; consequently, MPW code resource have to pretend in many ways that
they are apps. Hence that entire tech note about code resources and A5.
Blech.
> So maybe the question is, when the jGNE event is dispatched to the code
> within my INIT, must I set A5 for some reason? Even though I am not
> interested in globals (just the parameters on the stack)?
Again as I said in email, if your code does not use statically allocated
variables (locals declared 'static' or globals), you may still need to set
up A5 if your filter calls other routines, depending on how MPW finds
those routines. Probably it finds them PC-relative, but it may find them
A5-relative. Perhaps some MPW guru can shed light on this.
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"Even during a particularly harsh (Colorado) winter... many of the
300 families in the VCTV (movies-on-demand) trial continued to go
to video stores." -- eis@murrow.tufts.edu, in Wired 2.09 p62
+++++++++++++++++++++++++++
>From Jaeger@fquest.com (Brian Stern)
Date: 19 Aug 1994 02:36:45 GMT
Organization: The University of Texas at Austin, Austin, Texas
In article <jedavis.777254033@Xenon.Stanford.EDU>,
jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
> On a side note.. I dont suppose you have any idea if I can
> allocate some memory in a jGNEfilter? I dont mind stealing
> from the host app. I want to muck with the clipboard, so need
> a couple handles that dont mind being resized by the Scrap calls.
>
> -James
Since jGNEFilters are called from WNE/GNE and both of those traps are
documented as moving or purging memory, Yes you can allocate memory from
inside a jGNEFilter. If you want the memory to last longer than one pass
through your filter make sure to allocate the memory in the system heap,
otherwise it will be lost if the app quits. If the memory will be
allocated and disposed within one pass of the filter it can go in the
application's heap.
--
Brian Stern :-{)}
Jaeger@fquest.com
+++++++++++++++++++++++++++
>From jedavis@Xenon.Stanford.EDU (James Edward Davis)
Date: 18 Aug 94 18:51:13 GMT
Organization: Stanford University: Computer Science Department
larson@oahu.cs.ucla.edu (Christopher Larson) writes:
>In article <32tr42$pfg@hp-col.col.hp.com> chrism@col.hp.com (Chris Magnuson) writes:
>> So maybe the question is, when the jGNE event is dispatched to the code
>> within my INIT, must I set A5 for some reason? Even though I am not
>> interested in globals (just the parameters on the stack)?
>If you don't use (or cause to be used) any globals, you don't need an A5
>world, and, therefore, you don't need to set A5.
Yes, but remember that some Quickdraw globals are offset from A5 as
well. You might not need *your* A5, but you will need a valid one.
I bring this up, because inside your jGNEfilter you wont
neccessarily get one. You can set the A5 of the
currently executing application from the low memory global CurrentA5,
but remember to put back whatever stuffs was in A5 to start with.
James Davis : jedavis@cs.stanford.edu
+++++++++++++++++++++++++++
>From larson@oahu.cs.ucla.edu (Christopher Larson)
Date: Thu, 18 Aug 94 21:05:17 GMT
Organization: UCLA, Computer Science Department
James said:
>I said:
>>Chris Magnuson said:
>>> So maybe the question is, when the jGNE event is dispatched to the code
>>> within my INIT, must I set A5 for some reason? Even though I am not
>>> interested in globals (just the parameters on the stack)?
>
>>If you don't use (or cause to be used) any globals, you don't need an A5
>>world, and, therefore, you don't need to set A5.
>
>Yes, but remember that some Quickdraw globals are offset from A5 as
>well.
Making any calls which require Quickdraw globals count as causing globals
to be used. (Perhaps I should have made that point clear :-).
> You might not need *your* A5, but you will need a valid one.
Why? If I don't use Quickdraw or my own globals, I shouldn't (see caveat
below) need an A5 world and shouldn't care what the value of A5 is. I've
written numerous code resources and trap patches (though never a jGNE
filter). I've never needed an A5 world of my own (meaning belonging to
the code resource), and only needed to borrow the current application's
A5 when using Quickdraw globals. Unless jGNE filters are inherently
different, I don't see why one must run with a valid A5. (I didn't
intend this to sound at all like a flame. I'm just trying to get to
the bottom of this too.)
caveat: As Peter Lewis pointed out, calls to other routines within
code resources may use a jump table, which may use A5. Consult your
development system regarding this. (I'm paraphrasing, excuse me if I've
misinterpreted you, Peter.)
>I bring this up, because inside your jGNEfilter you wont neccessarily get
>one.
You sure won't.
>You can set the A5 of the currently executing application from the low
>memory global CurrentA5, but remember to put back whatever stuffs was in
>A5 to start with.
An invaluable piece of information. Saved my hiney many times.
--Chris
_______________________________________________________________________________
Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant
L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious
Death to the Trojans! Go Bruins!
(Insert disclaimer here)
Internet: larson@kingston.cs.ucla.edu
+++++++++++++++++++++++++++
>From jedavis@Xenon.Stanford.EDU (James Edward Davis)
Date: 18 Aug 94 23:53:53 GMT
Organization: Stanford University: Computer Science Department
larson@oahu.cs.ucla.edu (Christopher Larson) writes:
>> You might not need *your* A5, but you will need a valid one.
>Why? If I don't use Quickdraw or my own globals, I shouldn't (see caveat
>below) need an A5 world and shouldn't care what the value of A5 is. I've
>written numerous code resources and trap patches (though never a jGNE
>filter). I've never needed an A5 world of my own (meaning belonging to
>the code resource), and only needed to borrow the current application's
>A5 when using Quickdraw globals. Unless jGNE filters are inherently
>different, I don't see why one must run with a valid A5. (I didn't
>intend this to sound at all like a flame. I'm just trying to get to
>the bottom of this too.)
You're correct. I phrased something badly. I had meant to
suggest that stealing the current applications A5 would do
for quickdraw globals, if you didnt have one of your own handy.
On a side note.. I dont suppose you have any idea if I can
allocate some memory in a jGNEfilter? I dont mind stealing
from the host app. I want to muck with the clipboard, so need
a couple handles that dont mind being resized by the Scrap calls.
-James
+++++++++++++++++++++++++++
>From jedavis@Xenon.Stanford.EDU (James Edward Davis)
Date: 19 Aug 94 09:42:08 GMT
Organization: Stanford University: Computer Science Department
Jaeger@fquest.com (Brian Stern) writes:
>In article <32tr42$pfg@hp-col.col.hp.com>, chrism@col.hp.com (Chris
>Magnuson) wrote:
>> Pete Gontier (gurgle@dnai.com) wrote:
>> : In article <32s8eq$kdr@hp-col.col.hp.com>,
>> : chrism@col.hp.com (Chris Magnuson) wrote:
>>
>> So maybe the question is, when the jGNE event is dispatched to the code
>> within my INIT, must I set A5 for some reason? Even though I am not
>> interested in globals (just the parameters on the stack)?
>>
>> chrism@col.hp.com
>In order to function properly any jGNEFilter has to insert itself into the
>chain of all jGNEFilters. When your filter exits it needs to jump to the
>previous filter. The address of the previous filter must be saved at the
>time that you install your filter. This saved address must be a global.
Global? Well not really. Its not really good style, but Ive seen it done
by stuffing the address into your code at install time. The same way
many people store their app A5, with code that self modifies to
contain the location.
For that matter, where should I store my apps A5, so I can reset
it without using self modifying code?
-James
+++++++++++++++++++++++++++
>From larson@oahu.cs.ucla.edu (Christopher Larson)
Date: Fri, 19 Aug 94 16:15:35 GMT
Organization: UCLA, Computer Science Department
In article <jedavis.777289328@Xenon.Stanford.EDU> jedavis@Xenon.Stanford.EDU (James Edward Davis) writes:
>Jaeger@fquest.com (Brian Stern) writes:
>>In order to function properly any jGNEFilter has to insert itself into the
>>chain of all jGNEFilters. When your filter exits it needs to jump to the
>>previous filter. The address of the previous filter must be saved at the
>>time that you install your filter. This saved address must be a global.
>
>Global? Well not really. Its not really good style, but Ive seen it done
>by stuffing the address into your code at install time. The same way
>many people store their app A5, with code that self modifies to
>contain the location.
I'm not sure this strategy counts as self-modification if the installed
code is contained in its own resource. When the app (INIT, whatever) loads
the resource, before detaching and installing, it's just data. If it's
modified at this point, I don't think you will have any problems (still
need to flush caches though), because the resource has never been loaded
as code. If the code to be installed is in your 'CODE' resources, all
bets are off. (Comments on this welcome....)
>For that matter, where should I store my apps A5, so I can reset
>it without using self modifying code?
Well, you could use the above strategy, or if that is still to self-modify-
ish, you could install a Gestalt selector. Note that trickery to recover your
A5 is only necessary if your code might run when your app is switched out or
at interrupt time. If this is not the case, you can recover it from CurrentA5,
as you suggested earlier.
Hmmm. This raises an interesting question. If an app installs a jGNEFilter,
is that filter visible to all other applications, or is it more like trap
patches (which, if done from an app, are only visible to the installing app)?
Anyone?
Since this thread is about jGNEFilters, I assume your question was specific
to recovering A5 from a jGNEFilter/trap patch kind of situation. If not, mail
me with the specifics.
--Chris
_______________________________________________________________________________
Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant
L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious
Death to the Trojans! Go Bruins!
(Insert disclaimer here)
Internet: larson@kingston.cs.ucla.edu
+++++++++++++++++++++++++++
>From larson@oahu.cs.ucla.edu (Christopher Larson)
Date: Fri, 19 Aug 94 16:22:01 GMT
Organization: UCLA, Computer Science Department
In article <Jaeger-1808942138440001@slip-15-7.ots.utexas.edu> Jaeger@fquest.com (Brian Stern) writes:
>In article <jedavis.777254033@Xenon.Stanford.EDU>,
>jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
>
>> On a side note.. I dont suppose you have any idea if I can
>> allocate some memory in a jGNEfilter? I dont mind stealing
>
>Since jGNEFilters are called from WNE/GNE and both of those traps are
>documented as moving or purging memory, Yes you can allocate memory from
>inside a jGNEFilter. If you want the memory to last longer than one pass
>through your filter make sure to allocate the memory in the system heap,
>otherwise it will be lost if the app quits.
Or, you could receive consecutive calls from two different applications.
Best, in any case, to allocate from the system heap if you want persistance.
>If the memory will be allocated and disposed within one pass of the filter
>it can go in the application's heap.
Or maybe temporary memory if you don't want to use the app's heap.
--Chris
_______________________________________________________________________________
Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant
L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious
Death to the Trojans! Go Bruins!
(Insert disclaimer here)
Internet: larson@kingston.cs.ucla.edu
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Fri, 19 Aug 1994 09:45:18 -0800
Organization: Integer Poet Software
In article <1994Aug19.161535.10734@cs.ucla.edu>, larson@oahu.cs.ucla.edu
(Christopher Larson) wrote:
> If an app installs a jGNEFilter,
> is that filter visible to all other applications, or is it more like trap
> patches (which, if done from an app, are only visible to the installing app)?
It's visible to all other applications.
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"Even during a particularly harsh (Colorado) winter... many of the
300 families in the VCTV (movies-on-demand) trial continued to go
to video stores." -- eis@murrow.tufts.edu, in Wired 2.09 p62
+++++++++++++++++++++++++++
>From Jaeger@fquest.com (Brian Stern)
Date: 19 Aug 1994 16:43:20 GMT
Organization: The University of Texas at Austin, Austin, Texas
In article <jedavis.777289328@Xenon.Stanford.EDU>,
jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
> Jaeger@fquest.com (Brian Stern) writes:
>
> >In order to function properly any jGNEFilter has to insert itself into the
> >chain of all jGNEFilters. When your filter exits it needs to jump to the
> >previous filter. The address of the previous filter must be saved at the
> >time that you install your filter. This saved address must be a global.
>
> Global? Well not really. Its not really good style, but Ive seen it done
> by stuffing the address into your code at install time. The same way
> many people store their app A5, with code that self modifies to
> contain the location.
> For that matter, where should I store my apps A5, so I can reset
> it without using self modifying code?
>
> -James
App? I thought we were talking about about an INIT. Installing a
jGNEFilter from an app has a number of problems to worry about. I would
probably write the filter as a code resource using A4 addressing. To
install it I'd load the resource into the system heap, set up A0, and jump
to it from the app to initilize it. It would save A5 for later use. It
would also have to make sure that the app still existed. The A4 mechanism
as used by Think C is also a self-modifying mechanism and I don't see any
clean way around it.
Having said that, I recently came across some code in a package called
Extension Shell by Dair Grant that uses A4 addressing without being
self-modifying. Here's the code:
WRITTEN BY:
Eric Shapiro (from July 1993 BYTE article, and the supporting source code)
// Saves the current value of A4 on the stack, and puts the address of main
// into A4. Should be called at start of stand-alone code resource to
access globals.
#define GetGlobals() asm { \
move.l A4, -(SP) ; save old A4 \
lea main, A4 ; get globals \
}
// The converse of GetGlobals(). Restore the value of A4
#define UngetGlobals() asm { \
move.l (SP)+, A4 ; restore A4 from stack \
}
This is dependent on main being at the beginning of your code resource and
on your compiler compiling the code resource using A4 addressing.
--
Brian Stern :-{)}
Jaeger@fquest.com
+++++++++++++++++++++++++++
>From bjaques@vanbc.wimsey.com (Barton Jaques)
Date: Fri, 19 Aug 1994 09:36:35 -0700
Organization: Wimsey Information Services
I spent many long hours slaving over my hot jGNEFilter before it worked
correctly. It is the sloppiest hack I've seen in a while, but it works
great. In short, here's what I do:
• I have a separate jGNEFilter.π project which compiles into a single
resource.
• My INIT or DRVR reads that resource, detaches it, locks it.
• At startup time, my INIT or DRVR reads the current value of jGNEFilter,
pokes it into my patch resource, then sticks the address of my patch
resource into jGNEFilter.
• I have another handle which contains useful "global" variables and
pointers to procedures contained in other code resources. I poke the handle
into my detached jGNE resource. This way I have access to "globals" which I
have scattered through different code resources … yet I don't have to
fiddle with A5.
• The way I do this is by initialising a couple of local variables in my
patch resource as follows:
globRecH globalsH = 0xEEEEEEEE;
long nextGNEFilter = 0xDDDDDDDD;
My INIT or DRVR scans the resource, finds 0xEEEEEEEE, and overwrites it
with my "globals" handle. Then it scans for 0xDDDDDDDD, and overwrites it
with the pointer to the next GNE filter.
• If my GNEFilter calls a procedure in another of my code resources, THEN I
need to set up A4/A5 as appropriate, and put it back before I return to my
patch.
• When I want to de-install my driver, etc., I cauterise my patch by
plugging 0x00000000 where my globals handle was. The filter then knows that
it has been deactivated, so it passes to the next filter without doing
anything. I can always restore the patch simply by poking globH back in
again.
This is the code in THINK C 68K. It surely will not work under another
environment without serious modification, but it should illustrate the
idea.
void
main() {
globRecH globH = (globRecH)0xEEEEEEEE;
long nextGNEFilter = 0xDDDDDDDD;
EventRecord *filteredEventP;
// declare any other local vars you need
Ptr stackP; // stackP MUST be last local var declared
// move.l (a7), -(a7) ; In actual res this line must precede LINK A6
// ; In ResEdit, insert '2F17' as 1st word in res
// ; then move 2nd-last byte (= 4E5E) to
// ; precede 5th-last byte (= 4A97)
asm{
movem.l a7, stackP ; make copy of stack pointer
movem.l a0-a3/d0-d7, -(sp) ; save registers
}
// if nextGNEFilter exists we must fiddle with stack to insert it
if (nextGNEFilter) {
stackP += ((Ptr)&globH - (Ptr)&stackP) + 8;
*(long*)stackP = nextGNEFilter;
}
// do nothing if no globals
if (globH) {
// get a pointer to the event record
asm{
move.l a1, filteredEventP ; test a1 (EventPtr)
}
eventwhat = filteredEventP->what;
// now we can do our stuff
}
// restore registers and stack
asm{
movem.l (sp)+, d0-d7/a0-a3 ; restore all registers
tst.l (sp) ; in actual res these lines follow UNLK A6 (see note
above)
bne @END ;
tst.l (sp)+ ;
@END
}
// control now passes to next GNEFilter handler if any
}
--
bjaques@vanbc.wimsey.com
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Fri, 19 Aug 1994 12:20:28 -0800
Organization: Integer Poet Software
In article <bjaques-190894093636@pme22.pomo.wis.net>,
bjaques@vanbc.wimsey.com (Barton Jaques) wrote:
> I spent many long hours slaving over my hot jGNEFilter before it worked
> correctly. It is the sloppiest hack I've seen in a while, but it works
> great. In short, here's what I do...
With all due respect for your long hours, quite frankly this all seems
very convoluted and mildly dangerous. If any step in the development
process goes wrong, the program fails at runtime. There are a minimum of
helpful compile-time checks, and it's difficult to see why any one part of
it works the way it does without understanding the whole picture. I'm glad
it works for you, but it seems a lot simpler and a lot cleaner to simply
use a strategy like that illustrated in "jGNE Helper" or whatever the hell
that monthly posting is called. (It may sound like I didn't write it
because I can't even remember its name, but I did write it, and you should
assume I am accordingly biased.)
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"Even during a particularly harsh (Colorado) winter... many of the
300 families in the VCTV (movies-on-demand) trial continued to go
to video stores." -- eis@murrow.tufts.edu, in Wired 2.09 p62
+++++++++++++++++++++++++++
>From Jaeger@fquest.com (Brian Stern)
Date: 20 Aug 1994 00:25:40 GMT
Organization: The University of Texas at Austin, Austin, Texas
In article <bjaques-190894093636@pme22.pomo.wis.net>,
bjaques@vanbc.wimsey.com (Barton Jaques) wrote:
> I spent many long hours slaving over my hot jGNEFilter before it worked
> correctly. It is the sloppiest hack I've seen in a while, but it works
> great. In short, here's what I do:
Or, you could simply use A4 addressing to access your globals from your
Filter. You can easily set a Boolean flag to let your Filter know if it's
supposed to do anything.
I don't trust any code building method that has instructions in it like '
In ResEdit, insert '2F17' as 1st word in res then move 2nd-last byte (=
4E5E) to precede 5th-last byte (= 4A97)'.
In programming like in most things simpler is usually better. There are
lot's simpler ways to do it than this.
> --
> bjaques@vanbc.wimsey.com
--
Brian Stern :-{)}
Jaeger@fquest.com
+++++++++++++++++++++++++++
>From jedavis@Xenon.Stanford.EDU (James Edward Davis)
Date: 20 Aug 94 17:24:09 GMT
Organization: Stanford University: Computer Science Department
larson@oahu.cs.ucla.edu (Christopher Larson) writes:
>In article <jedavis.777289328@Xenon.Stanford.EDU> jedavis@Xenon.Stanford.EDU (James Edward Davis) writes:
>>Jaeger@fquest.com (Brian Stern) writes:
>Well, you could use the above strategy, or if that is still to self-modify-
>ish, you could install a Gestalt selector. Note that trickery to recover your
>A5 is only necessary if your code might run when your app is switched out or
>at interrupt time. If this is not the case, you can recover it from CurrentA5,
>as you suggested earlier.
>Hmmm. This raises an interesting question. If an app installs a jGNEFilter,
>is that filter visible to all other applications, or is it more like trap
>patches (which, if done from an app, are only visible to the installing app)?
>Anyone?
The jGNE filter *is* active across all apps. The low memory global that
points to the filter chain, is not changed by context switches. This
means you have to be very careful if you install a filter with code
in your app heap, since if you quit without cleanup, theres a dangling
reference and the machine will crash.
-James
+++++++++++++++++++++++++++
>From kluev@jonathan.srcc.msu.su (Kluev)
Date: Mon, 22 Aug 94 23:02:46 +0400
Organization: (none)
In article <jedavis.777403449@Xenon.Stanford.EDU>
jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
> The jGNE filter *is* active across all apps. The low memory global
that
> points to the filter chain, is not changed by context switches. This
> means you have to be very careful if you install a filter with code
> in your app heap, since if you quit without cleanup, theres a
dangling
> reference and the machine will crash.
One should be careful about this cleanup. One shouldn't restore
original value in jGNEFilter, because someone may install gne
filter on top of one's. Restoring jGNEFilter to original value
will remove someone's filter and may crash him. The better
solution is to install one's filter into system heap, never
remove it, check if filter was already installed (Gestalt is
one solution) (not to install it twice), set/clear flag on
application's startup/exit to turn filter's activity on/off.
Michael Kluev.
+++++++++++++++++++++++++++
>From jedavis@Xenon.Stanford.EDU (James Edward Davis)
Date: 23 Aug 94 02:50:02 GMT
Organization: Stanford University: Computer Science Department
kluev@jonathan.srcc.msu.su (Kluev) writes:
>In article <jedavis.777403449@Xenon.Stanford.EDU>
>jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
>One should be careful about this cleanup. One shouldn't restore
>original value in jGNEFilter, because someone may install gne
>filter on top of one's. Restoring jGNEFilter to original value
>will remove someone's filter and may crash him. The better
>solution is to install one's filter into system heap, never
>remove it, check if filter was already installed (Gestalt is
>one solution) (not to install it twice), set/clear flag on
>application's startup/exit to turn filter's activity on/off.
Yes, that would work but Id rather not leave memory allocated
in the system heap. But your right about another being installed
over mine. I allocate a small block in the system heap that just
jumps to my code in the application heap. When I want to deinstall,
I check to see if the front jGNEfilter is me. If it is, I can
just reset the pointer. If its not, I change my stub to
jump to the original address instead of my code. I only end up
wasting a little system heap that way. I cant claim credit
for the technique. I got a snippet from someone else, thought
it was clever, and used it.
-James
+++++++++++++++++++++++++++
>From h+@nada.kth.se (Jon W{tte)
Date: Tue, 23 Aug 1994 09:49:02 +0200
Organization: Royal Institute of Something or other
In article <jedavis.777610202@Xenon.Stanford.EDU>,
jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
>Yes, that would work but Id rather not leave memory allocated
>in the system heap. But your right about another being installed
>over mine. I allocate a small block in the system heap that just
>jumps to my code in the application heap. When I want to deinstall,
I hope you remember to flush the cache when you change this
value...
Cheers,
/ h+
--
Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
"Psychotherapist" - "Phycho-The-Rapist"
Pure coincidence? You decide!
+++++++++++++++++++++++++++
>From jedavis@Xenon.Stanford.EDU (James Edward Davis)
Date: 23 Aug 94 22:00:51 GMT
Organization: Stanford University: Computer Science Department
h+@nada.kth.se (Jon W{tte) writes:
>In article <jedavis.777610202@Xenon.Stanford.EDU>,
>jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
>>Yes, that would work but Id rather not leave memory allocated
>>in the system heap. But your right about another being installed
>>over mine. I allocate a small block in the system heap that just
>>jumps to my code in the application heap. When I want to deinstall,
>I hope you remember to flush the cache when you change this
>value...
Why.. thats an excellent point. I dont flush it, but it seems to
work fine on my C610. I think Ive been very lucky.. Ill go change
that. Unless anyone can think of a legit reason its working.
Thanks,
James
+++++++++++++++++++++++++++
>From kluev@jonathan.srcc.msu.su (Kluev)
Date: Wed, 24 Aug 94 21:13:06 +0400
Organization: (none)
In article <jedavis.777679251@Xenon.Stanford.EDU>
jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
> h+@nada.kth.se (Jon W{tte) writes:
>
> >In article <jedavis.777610202@Xenon.Stanford.EDU>,
> >jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote:
>
> >>Yes, that would work but Id rather not leave memory allocated
> >>in the system heap. But your right about another being installed
> >>over mine. I allocate a small block in the system heap that just
> >>jumps to my code in the application heap. When I want to deinstall,
>
> >I hope you remember to flush the cache when you change this
> >value...
>
> Why.. thats an excellent point. I dont flush it, but it seems to
> work fine on my C610. I think Ive been very lucky.. Ill go change
> that. Unless anyone can think of a legit reason its working.
This depends on processor type and what your code is looked like.
If it is looked like that:
JMP Address; 0x4EF9 0x12345678; where 0x12345678 is modified address,
you need to flush cache on 040 processors.
If it is looked like this:
MOVE.L *+$0006, -(sp); 0x2F3A0004;
RTS; 0x4E75
DC.L 0x12345678; 0x12345678; where 0x12345678 is modified addr,
don't worry about flushing cache. (DC.L will not run as code.)
/* From MacTech magazine */
Michael Kluev.
---------------------------
End of C.S.M.P. Digest
**********************